package com.efrei.schoolmanager.views;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

import org.hibernate.HibernateException;

import com.efrei.schoolmanager.controlers.ControleurClasse;
import com.efrei.schoolmanager.controlers.ControleurEleve;
import com.efrei.schoolmanager.controlers.ControleurEleves;
import com.efrei.schoolmanager.exceptions.LogicException;
import com.efrei.schoolmanager.model.hibernate.HibernateUtil;
import com.efrei.schoolmanager.tools.Tools;

public class VueGenerale extends JFrame {
	private static final long serialVersionUID = -7291488441704843383L;

	private static String TITLE = "School Manager : bienvenue";

	private final VueGenerale jf;

	// JPanels
	private final JPanel contenuPanel;

	private BarreChargement barreChargement;

	public VueGenerale() {
		jf = this;
		// Lancement du splash screen pendant le demarrage de l'application
		SplashScreen splash = SplashScreen.getInstance("images/splash.png");
		try {
			HibernateUtil.configureSessionFactory();
		} catch (LogicException e) {
			displayError(e);
			System.exit(1);
		} catch (Exception e) {
			e.printStackTrace();
			Tools.displayError(
					"Connection à la base impossible. Verifiez les parametres.",
					"Erreur");
			System.exit(1);
		}
		// Quitter le splash screen
		splash.end();
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		} catch (Exception e) {
			System.err
					.println("Theme Nimbus non trouvé, test celui par défaut");
			try {
				UIManager.setLookAndFeel(UIManager
						.getSystemLookAndFeelClassName());
			} catch (Exception ex) {
				System.err.println("Echec, on garde Metal.");
			}
		}

		initMenuJPanel();

		configurerFenetre();
		addWindowListener(new QuitterAppliWindowsListener());
		contenuPanel = new JPanel();
		configurerContenu(new VueAccueil());
		this.add(contenuPanel);
		JScrollPane scrollBar = new JScrollPane(contenuPanel,
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		this.add(scrollBar);
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		setVisible(true);
	}

	public void configurerContenu(JPanel fenetre) {
		contenuPanel.removeAll();
		contenuPanel.add(fenetre, BorderLayout.CENTER);
		setVisible(true);
		contenuPanel.updateUI();
	}

	/**
	 * Effacer l'écran courant
	 */
	public void removePanel() {
		contenuPanel.removeAll();
		contenuPanel.add(new VueAccueil());
		setVisible(true);
		contenuPanel.updateUI();
	}

	/**
	 * Configurer les options de la vue
	 * 
	 */
	private void configurerFenetre() {
		/* Fenetre en plein ecran */
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		Dimension dim = new Dimension(1252, 857);
		setMinimumSize(dim);
		setSize(dim);
		setTitle(TITLE);
	}

	private void initMenuJPanel() {
		JMenuBar generalmenuBar = new JMenuBar();

		// Partie Fichier
		JMenu fichierMenu = new JMenu("Fichier");
		JMenuItem accueilMenuItem = new JMenuItem("Accueil");
		accueilMenuItem.addActionListener(new AccueilListener(this));
		JMenuItem quitterMenuItem = new JMenuItem("Quitter");
		quitterMenuItem.addActionListener(new QuitterAppliListener());
		fichierMenu.add(accueilMenuItem);
		fichierMenu.add(quitterMenuItem);

		// Partie Gestion Administrative
		JMenu gestAdminMenu = new JMenu("Gestion Administrative");
		JMenu gestElevesMenu = new JMenu("Eleves");
		gestAdminMenu.add(gestElevesMenu);

		// Eleves
		JMenuItem ajouterEleveMenuItem = new JMenuItem("Ajouter eleve");
		ajouterEleveMenuItem.addActionListener(new AjouterEleveListener());
		gestElevesMenu.add(ajouterEleveMenuItem);

		// Eleves
		JMenuItem listeEleveMenuItem = new JMenuItem("Liste des eleves");
		listeEleveMenuItem.addActionListener(new ListerEleveListener());
		gestElevesMenu.add(listeEleveMenuItem);

		// Classes
		JMenuItem listeClasseMenuItem = new JMenuItem("Liste des Classes");
		listeClasseMenuItem.addActionListener(new ListeClasseListener());
		gestAdminMenu.add(listeClasseMenuItem);

		// Partie Gestion Académique
		JMenu gestAcademiqueMenu = new JMenu("Gestion Académique");
		JMenuItem ajoutNotesItem = new JMenuItem("Gestion des Notes");
		ajoutNotesItem.addActionListener(new GestionNotesListener(this));
		gestAcademiqueMenu.add(ajoutNotesItem);

		// Partie Impression
		JMenu impressionMenu = new JMenu("Impressions");
		JMenuItem convocAbsencesItem = new JMenuItem(
				"Convocation pour absences");
		convocAbsencesItem.addActionListener(new ConvocationAbsencesListener());
		JMenuItem convocItem = new JMenuItem("Convocation ");
		convocItem.addActionListener(new ConvocationListener());
		JMenuItem bulletinAbsencesItem = new JMenuItem("Bulletin d'absences");
		bulletinAbsencesItem.addActionListener(new BulletinAbsencesListener());
		JMenuItem certifScolariteItem = new JMenuItem("Certificat de scolarité");
		certifScolariteItem
				.addActionListener(new CertificatScolariteListener());
		JMenuItem releveNotesItem = new JMenuItem("Releve de notes");
		releveNotesItem.addActionListener(new ReleveNotesListener());
		JMenuItem bulletinNotesItem = new JMenuItem("Bulletin de notes");
		bulletinNotesItem.addActionListener(new BulletinNotesListener());
		JMenuItem demandeBourseItem = new JMenuItem("Demande de bourse");
		demandeBourseItem.addActionListener(new DemandeBourseListener());
		impressionMenu.add(convocAbsencesItem);
		impressionMenu.add(convocItem);
		impressionMenu.add(bulletinAbsencesItem);
		impressionMenu.add(certifScolariteItem);
		impressionMenu.add(releveNotesItem);
		impressionMenu.add(bulletinNotesItem);
		impressionMenu.add(demandeBourseItem);

		JMenu plusMenu = new JMenu("Plus");
		JMenuItem aProposItem = new JMenuItem("A propos");
		aProposItem.addActionListener(new AProposListener(this));
		plusMenu.add(aProposItem);

		generalmenuBar.add(fichierMenu);
		generalmenuBar.add(gestAdminMenu);
		generalmenuBar.add(gestAcademiqueMenu);
		generalmenuBar.add(impressionMenu);
		generalmenuBar.add(plusMenu);
		this.setJMenuBar(generalmenuBar);
	}

	private void confirmationClosing() {
		int option = JOptionPane.showConfirmDialog(null,
				"Voulez-vous Quitter l'application ?",
				"Quitter School Manager", JOptionPane.YES_NO_OPTION,
				JOptionPane.QUESTION_MESSAGE);

		if (option == 0) {
			System.exit(ABORT);
		}
	}

	/* Listeners pour le menu */
	class AjouterEleveListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			ControleurEleve cae = null;
			try {
				cae = new ControleurEleve(null);
			} catch (Exception e1) {
				displayError(e1);
			}
			if (cae != null) {
				VueAjoutEleve vae = new VueAjoutEleve(jf, cae);
				configurerContenu(vae);
			}
		}

	}

	class ConvocationListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			VueConvocation vc;
			try {
				vc = new VueConvocation(jf);
				configurerContenu(vc);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class ConvocationAbsencesListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			try {
				VueAvertissementAbsence vabs = new VueAvertissementAbsence(jf);
				configurerContenu(vabs);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class BulletinAbsencesListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				VueBulletinAbsences vba = new VueBulletinAbsences(jf);
				configurerContenu(vba);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class CertificatScolariteListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				VueCertificatScolarite vcs = new VueCertificatScolarite(jf);
				configurerContenu(vcs);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class DemandeBourseListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				VueDemandeBourse vdb = new VueDemandeBourse(jf);
				configurerContenu(vdb);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class ReleveNotesListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			VueReleveNotes vbn = null;
			try {
				vbn = new VueReleveNotes(jf);
			} catch (HibernateException e1) {
				e1.printStackTrace();
			} catch (LogicException e1) {
				e1.printStackTrace();
			}
			configurerContenu(vbn);

		}

	}

	class BulletinNotesListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				VueBulletinNotes vbn = new VueBulletinNotes(jf);
				configurerContenu(vbn);
			} catch (Exception e1) {
				displayError(e1);
			}
		}

	}

	class QuitterAppliListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			confirmationClosing();

		}
	}

	class ListeClasseListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			ControleurClasse controleur = null;
			try {
				controleur = new ControleurClasse();
			} catch (Exception e1) {
				displayError(e1);
			}
			if (controleur != null) {
				VueListerClasse vac = new VueListerClasse(jf, controleur);
				configurerContenu(vac);
			}
		}

	}

	class ListerEleveListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			ControleurEleves ce = null;
			try {
				ce = new ControleurEleves();
			} catch (Exception e1) {
				displayError(e1);
			}
			if (ce != null) {
				VueListerEleves vle = new VueListerEleves(jf, ce);
				configurerContenu(vle);
			}
		}

	}

	class GestionNotesListener implements ActionListener {
		private VueGestionNotes vue;
		private final VueGenerale vueGenerale;

		public GestionNotesListener(VueGenerale vueGenerale) {
			this.vueGenerale = vueGenerale;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				vue = new VueGestionNotes(vueGenerale);
				vueGenerale.configurerContenu(vue);
			} catch (Exception e1) {
				displayError(e1);
			}
		}
	}

	class AccueilListener implements ActionListener {
		private final VueGenerale vueGenerale;

		public AccueilListener(VueGenerale vueGenerale) {
			this.vueGenerale = vueGenerale;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				vueGenerale.configurerContenu(new VueAccueil());
			} catch (Exception e1) {
				displayError(e1);
			}
		}
	}

	class AProposListener implements ActionListener {
		private final VueGenerale vueGenerale;

		public AProposListener(VueGenerale vueGenerale) {
			this.vueGenerale = vueGenerale;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			JOptionPane
					.showMessageDialog(
							vueGenerale,
							"Cette application a été réalisée par:\n\n- Romain CROIZIER\n- Julien HAMMER\n- Pierrick GREZE\n\n Ce projet fonctionne grâce à la technologie Java.",
							"A propos", JOptionPane.PLAIN_MESSAGE);
		}
	}

	class QuitterAppliWindowsListener implements WindowListener {

		@Override
		public void windowActivated(WindowEvent e) {

		}

		@Override
		public void windowClosed(WindowEvent e) {

		}

		@Override
		public void windowClosing(WindowEvent e) {
			confirmationClosing();
		}

		@Override
		public void windowDeactivated(WindowEvent e) {

		}

		@Override
		public void windowDeiconified(WindowEvent e) {
		}

		@Override
		public void windowIconified(WindowEvent e) {
		}

		@Override
		public void windowOpened(WindowEvent e) {

		}

	}

	/**
	 * Afficher une barre de chargement
	 */
	public synchronized void startBarreChargement() {
		barreChargement = new BarreChargement(this);
		barreChargement.showDialog();
	}

	/**
	 * Fermer la barre de chargement
	 * 
	 */
	public synchronized void stopBarreChargement() {
		if (barreChargement != null) {
			barreChargement.close();
			barreChargement = null;
		}
	}

	/**
	 * Afficher le message de l'exception donnée en argument <br/>
	 * OU message generique si e == null
	 * 
	 * @param e
	 */
	public void displayError(Exception e) {
		if (e != null) {
			System.err.println(e.getMessage());
		}
		String title = "Erreur";
		String message = "Une erreur est survenue lors du chargement. Voir administrateur";
		// Les LogicException ont des messages explicites
		if (e != null && e instanceof LogicException)
			message = e.getMessage();
		Tools.displayError(message, title);
	}

}
